package com.cenntro.auth.service.impl;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cenntro.auth.mapper.SysRoleMapper;
import com.cenntro.auth.model.dbo.SysPermissionDO;
import com.cenntro.auth.model.dbo.SysRoleDO;
import com.cenntro.auth.model.dbo.SysRolePermissionRefDO;
import com.cenntro.auth.model.dbo.SysSooidRoleRefDO;
import com.cenntro.auth.model.vo.SysRoleVO;
import com.cenntro.auth.service.SysPermissionService;
import com.cenntro.auth.service.SysRolePermissionRefService;
import com.cenntro.auth.service.SysRoleService;
import com.cenntro.auth.service.SysSooidService;
import com.cenntro.auth.utils.BeanFill;
import com.cenntro.common.base.BaseServiceImpl;
import com.cenntro.common.util.ConvertorUtils;
import com.cenntro.common.websocket.ChannelSupervise;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;

/**
 * <p>
 * 角色表 服务实现类
 * </p>
 *
 * @author 
 * @since 2019-02-15
 */
@Service
public class SysRoleServiceImpl extends BaseServiceImpl<SysRoleMapper> implements SysRoleService {

    @Resource
    private SysRolePermissionRefService sysRolePermissionRefService;

    @Resource
    private com.cenntro.auth.service.SysSooidRoleRefService sysSooidRoleRefService;

    @Resource
    private SysPermissionService sysPermissionService;
    @Resource
    private SysSooidService sysSooidService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insert(Object t) {
        SysRoleVO sysRoleVO = (SysRoleVO) t;
        SysRoleDO role = new SysRoleDO();
        role.setRoleName(sysRoleVO.getRoleName());
        int count = super.selectCount(role);
        if (count == 0) {
            role = ConvertorUtils.deepConvert(sysRoleVO, SysRoleDO.class);
            BeanFill.fillByCreate(role);
            count = super.insert(role);
            final int roleId = role.getRoleId();
            if (StringUtils.isNotBlank(sysRoleVO.getPermssionIds())) {
                String[] ids = sysRoleVO.getPermssionIds().split(",");
                Arrays.stream(ids).forEach(permssionId -> {
                    SysRolePermissionRefDO sysRolePermissionRef = new SysRolePermissionRefDO();
                    sysRolePermissionRef.setCdt(new Date());
                    sysRolePermissionRef.setPermissionId(NumberUtils.toInt(permssionId));
                    sysRolePermissionRef.setRoleId(roleId);
                    sysRolePermissionRefService.insert(sysRolePermissionRef);
                });
            }
        } else {
            count = -1;
        }
        return count;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int update(Object t) {
        SysRoleVO sysRoleVO = (SysRoleVO) t;
        SysRoleDO role = null;
        if (!StringUtils.isBlank(sysRoleVO.getRoleName())) {
            role = super.selectOne(ImmutableMap.of("roleName", sysRoleVO.getRoleName()));
            if (role != null) {
                if (!role.getRoleId().equals(sysRoleVO.getRoleId())) {
                    return -1; // Result.error(MessageUtil.PARAM_ILLEGAL,
                               // MessageUtil.getMsg("ROLE_NAME_EXISTS",
                               // sysRoleVO.getRoleName()));
                }
            }
        }
        role = ConvertorUtils.deepConvert(sysRoleVO, SysRoleDO.class);
        BeanFill.fillByUpdate(role);
        super.update(role);
        final int roleId = role.getRoleId();
        sysRolePermissionRefService.deleteByRole(roleId);
        // 查询角色对应用户
        SysSooidRoleRefDO sysSooidRoleRef = new SysSooidRoleRefDO();
        sysSooidRoleRef.setRoleId(roleId);
        List<SysSooidRoleRefDO> refs = sysSooidRoleRefService.selectPage(sysSooidRoleRef);
        List<String> userList = Lists.newArrayList();
        String[] user = new String[refs.size()];
        List<String> StringPermissions = Lists.newArrayList();
        for (SysSooidRoleRefDO ref : refs) {
            userList.add(ref.getSooid().toString());
        }
        if (StringUtils.isNotBlank(sysRoleVO.getPermssionIds())) {
            String[] ids = sysRoleVO.getPermssionIds().split(",");
            List<Integer> permissionIds = Lists.newArrayList();
            Arrays.stream(ids).forEach(permssionId -> {
                permissionIds.add(NumberUtils.toInt(permssionId));
                SysRolePermissionRefDO sysRolePermissionRef = new SysRolePermissionRefDO();
                sysRolePermissionRef.setCdt(new Date());
                sysRolePermissionRef.setPermissionId(NumberUtils.toInt(permssionId));
                sysRolePermissionRef.setRoleId(roleId);
                sysRolePermissionRefService.insert(sysRolePermissionRef);
            });
            // 查询的角色的权限
            List<Map<String, Object>> permissions = sysPermissionService
                    .selectByMap(ImmutableMap.of("permIds", permissionIds));
            for (Map<String, Object> perm : permissions) {
                StringPermissions.add(perm.get("url").toString());
            }
        }
//        ChannelSupervise.send(userList.toArray(user), StringUtils.join(StringPermissions));
        sysSooidService.reflush(userList.toArray(user), StringUtils.join(StringPermissions), sysRoleVO.getRoleType());
        
        return 1;
    }

    public List<SysRoleDO> selectByUserId(Integer userId) {
        SysSooidRoleRefDO ref = new SysSooidRoleRefDO();
        ref.setSooid(userId);
        List<SysSooidRoleRefDO> list = sysSooidRoleRefService.selectPage(ref);
        if (CollectionUtils.isNotEmpty(list)) {
            List<Integer> roleIds = Lists.newArrayList();
            list.forEach(e -> {
                roleIds.add(e.getRoleId());
            });
            return this.selectByMap(ImmutableMap.of("roleIds", roleIds));
        }
        return Lists.newArrayList();
    }
}
